/**
 * Copyright (c) 2008, Mu Dynamics.
 *  All rights reserved.
 *  
 *   Redistribution and use in source and binary forms, with or without modification, 
 *   are permitted provided that the following conditions are met:
 *   
 *  - Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright notice, 
 *     this list of conditions and the following disclaimer in the documentation and/or 
 *     other materials provided with the distribution.
 *  - Neither the name of the "Mu Dynamics" nor the names of its contributors may be used 
 *     to endorse  or promote products derived from this software without specific prior 
 *     written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.mu.jacob.core.ant;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.Property;
import org.apache.tools.ant.types.DataType;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PropertySet;
import org.apache.tools.ant.types.Reference;

import com.mu.jacob.core.generator.ModelSet;

/**
 * Model configuration type. 
 * Model type contains all model classes and configures its class path.
 * @author Adam Smyczek
 */
public class ModelType extends DataType {

	/* helpers */
	private final PathHelper pathHelper;
	private final PropertyHelper propertyHelper;
	
	/* file sets containing model classes */
	private List<FileSet> filseSetList = new ArrayList<FileSet>();

	/* Element module class name */
	private String elementModule = null;
	
	/**
	 * Constructor with default path and property initialization
	 */
	public ModelType() {
		super();
		this.pathHelper = new PathHelper();
		this.propertyHelper = new PropertyHelper();
	}

	/**
	 * Create package set
	 * 
	 * @return package set
	 */
	public FileSet createFileset() {
		FileSet fileSet = new FileSet();
		filseSetList.add(fileSet);
		return fileSet;
	}

	/**
	 * Creates model sets from configured file sets
	 * @return model sets
	 */
	protected List<ModelSet> getModelSets() {
		List<ModelSet> result = new ArrayList<ModelSet>();
		for (FileSet fileSet : filseSetList) {
			// get file list
			DirectoryScanner scanner = fileSet.getDirectoryScanner(getProject());
			String[] fileList = scanner.getIncludedFiles();
			ModelSet modelSet = new ModelSet(
					fileSet.getDir(getProject()), 
					fileList);
			result.add(modelSet);
		}
		return result;
	}
	
	/**
	 * @return properties
	 */
	public Properties getProperties() {
		return propertyHelper.getProperties();
	}

	/**
	 * Add property set
	 * 
	 * @param propertySet
	 */
	public void addConfiguredPropertySet(PropertySet propertySet) {
		propertyHelper.addConfiguredPropertySet(propertySet);
	}

	/**
	 * Add a property
	 * 
	 * @param property
	 */
	public void addConfiguredProperty(Property property) {
		propertyHelper.addConfiguredProperty(property);
	}

	/**
	 * Set class path
	 * 
	 * @param classpath
	 */
	public void setPath(Path path) {
		pathHelper.setPath(path);
	}

	/**
	 * Add path to class path
	 * 
	 * @return class path
	 */
	public Path createPath() {
		return pathHelper.createPath();
	}

    /**
     * Set reference to class path
     * @param reference
     */
    public void setPathRef(Reference reference) {
    	pathHelper.setPathRef(reference);
    }

	/**
	 * set current loader to the context
	 * 
	 */
	protected void setThreadContextLoader() {
		pathHelper.setThreadContextLoader();
	}

	/**
	 * reset current context loader
	 */
	protected void resetThreadContextLoader() {
		pathHelper.resetThreadContextLoader();
	}
	
	/**
	 * @return type factory name
	 */
	public String getElementModule() {
		return elementModule;
	}

	/**
	 * Element module set from build.xml
	 * @param elementModule
	 */
	public void setElementModule(String elementModule) {
		this.elementModule = elementModule;
	}
	
	/**
	 * validate configuration
	 * @throws BuildException
	 */
	protected void validateConfiguration() throws BuildException {
		if (filseSetList.size() == 0) {
			throw new BuildException("No file sets defined!");
		}
	}

}
